package com.wisnews.controller.sec;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wisnews.config.aspectjLog.AopVisitLog;
import com.wisnews.pojo.Input;
import com.wisnews.pojo.Result;
import com.wisnews.pojo.sec.entity.Operator;
import com.wisnews.pojo.sec.vo.LoginVO;
import com.wisnews.service.Impl.QQEmailService;
import com.wisnews.service.sec.IRoleService;
import com.wisnews.service.sec.Impl.OperatorServiceImpl;
import com.wisnews.util.Constants;
import com.wisnews.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author yuyd
 * @since 2020-12-15
 */
@RestController
@RequestMapping("/operator")
@Slf4j
public class OperatorController {

    @Autowired
    private OperatorServiceImpl operatorService;

    @Autowired
    private QQEmailService sendEmail;

    @Autowired
    private IRoleService roleService;

    /** 
     * @description: 保存用户信息 
     * @param:
     * @return:
     * @author yuyd
     * @date: 2021/3/31 14:58
     */
    @RequestMapping("saveOperator")
    public Result saveOperator(@RequestBody Operator operator){
        log.info("==>saveOperator新增用户");

        Result<Map<String, String>> result;
        try {
            String res = checkInfo(operator);

            if ("ok".equals(res)){
                operatorService.save(operator);
                result = new Result<>(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE);
            }else {
                result = new Result<>(Constants.SYS_CODE.FAIL, res);
            }
        }catch (Exception e){
            result = new Result<>(Constants.SYS_CODE.FAIL, Constants.SYS_CODE.FAIL_MESSAGE);
            log.error("saveOperator"+e.toString()+"新增用户异常！");
        }

        return result;
    }
    
    /** 
     * @description: 更新用户 
     * @param:  
     * @return:  
     * @author yuyd
     * @date: 2021/3/31 14:58
     */
    @RequestMapping("updateOperator")
    public Result updateOperatorById(@RequestBody Operator operator){

        log.info("==>updateOperatorById 更新用户"+operator.getOperatorId());

        Result<Map<String, String>> result = null;
        try {
            String res = checkInfo(operator);

            if ("ok".equals(res)){
                operatorService.updateById(operator);
                result = new Result<>(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE);
            }else {
                result = new Result<>(Constants.SYS_CODE.FAIL, res);
            }
        }catch (Exception e){
            result = new Result<>(Constants.SYS_CODE.FAIL, Constants.SYS_CODE.FAIL_MESSAGE);
            log.error("==>updateOperatorById 更新用户用户异常！");
        }

        return result;
    }

    /**
     * @description: 验证添加用户信息是否冲突
     * @param:
     * @return:
     * @author yuyd
     * @date:
     */
    private String checkInfo(Operator operator) {


        boolean isupdate = false;
        LambdaQueryWrapper<Operator> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(Operator::getEmail,operator.getEmail());
        //更新信息查询
        if (StringUtils.isNotBlank(operator.getOperatorId())){
            lambdaQueryWrapper.ne(Operator::getOperatorId,operator.getOperatorId());
            isupdate = true;
        }
        List<Operator> list = operatorService.list(lambdaQueryWrapper);
        if (list.size() != 0){
            return "邮箱不可用！";
        }

        lambdaQueryWrapper.clear();
        if (isupdate){
            lambdaQueryWrapper.ne(Operator::getOperatorId,operator.getOperatorId());
        }
        lambdaQueryWrapper.eq(Operator::getCode,operator.getCode());
        List<Operator> list1 = operatorService.list(lambdaQueryWrapper);
        if (list1.size() != 0){
            return "用户名不可用！";
        }


        return "ok";
    }

    /**
     * @description: 后台用户登录
     * @param:  user request
     * @return:
     * @author yuyd
     * @date:
     */
    @RequestMapping("login")
    public Result adminogin(@RequestBody LoginVO user, HttpServletRequest request){
        // 获取当前用户
        Subject currentUser = SecurityUtils.getSubject();
        // 封装用户登录数据
        //系统管理员默认开启记住我功能
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword(),true);
        Result<Map<String, Object>> result = new Result<>(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE);
        Map<String, Object> data = new HashMap<>();
        // 登录 , 如果没有异常就登录成功
        try {
            currentUser.login(token);
            Session session = SecurityUtils.getSubject().getSession();
            //当前用户信息存入session
            Operator principal = (Operator) currentUser.getPrincipal();
            session.setAttribute(Constants.SYS_CODE.LOGIN_USER, principal);
            // 登录成功之后 设置session有效时间
            session.setTimeout(Constants.SYS_CODE.maxIdleTimeInMillis);
            //发送登录提示邮件
            String ipAddr = AopVisitLog.getIpAddr(request);
      String context =
          "亲爱的智慧新闻管理员,您的账户在IP："
              + ipAddr
              + "登录！("+ DateUtil.getCurrentDateTime() +")如非本人操作请尽快修改密码。本人操作请忽略。";
            sendEmail.sendSimpleMail(principal.getEmail(),"智慧新闻登录提醒",context);
            data.put("toPage", "index.html");
            data.put("user", principal);
        } catch (UnknownAccountException e) {
            result.setCode(Constants.SYS_CODE.FAIL);
            result.setMsg("用户名不存在");
        } catch (IncorrectCredentialsException e) {
            result.setCode(Constants.SYS_CODE.FAIL);
            result.setMsg("密码错误");
        } catch (Exception e) {
            result.setCode(Constants.SYS_CODE.FAIL);
            result.setMsg("系统异常请联系管理员:" + e.toString());
        }
        result.setData(data);
        return result;
    }

    /** 
     * @description: 注销登录
     * @param:  
     * @return:  
     * @author yuyd
     * @date:  
     */
    @RequestMapping(value = "loginOut",method = RequestMethod.POST)
    public Result loginOut() {
            SecurityUtils.getSubject().logout();
        return new Result(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE);
    }


    /** 
     * @description: 获取用户信息 
     * @param:  input
     * @return:  result
     * @author yuyd
     * @date:  
     */
    @RequestMapping("getOperatorInfo")
    public  Result<IPage<Operator>> getOperatorInfo(@RequestBody Input<Operator> operatorInput) {

        IPage<Operator> operatorPage = operatorService.getOperatorInfo4Page(operatorInput);

        Result<IPage<Operator>> result = new Result<IPage<Operator>>(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE,operatorPage);

        return result;
    }

    /** 
     * @description: 删除用户 
     * @param:  list 用户id列表
     * @return:  
     * @author yuyd
     * @date:  
     */
    @RequestMapping("delete")
    public Result<Map<String,Object>> deleteOperator4Ids(@RequestBody List<String> list) {
        log.error("执行==》deleteOperator4Ids prams"+ list.toString());

        Subject subject = SecurityUtils.getSubject();
        //检查是否选择了 超级用户 admin  至少要保留一个用户
        LambdaQueryWrapper<Operator> queryWrapper = new LambdaQueryWrapper<>();
        Operator admin = operatorService.getOne(queryWrapper.eq(Operator::getCode, "admin"));
        if (!Objects.equals(admin,null) && list.contains(admin.getOperatorId())){
            return  new Result<>(Constants.SYS_CODE.FAIL,"不能删除超级管理员！");
        }

        //检查操作权限
        if (subject.isPermitted(Constants.SYS_JURISDICTION.SYS_DELETE)){
            operatorService.removeByIds(list);
            return  new Result(Constants.SYS_CODE.SUCCESS,Constants.SYS_CODE.SUCCESS_MESSAGE);
        }else {
            return  new Result<>(Constants.SYS_CODE.FAIL,"您没有权限操作");
        }
    }

    /** 
     * @description: 查询当前登录用户的权限信息 
     * @param:  null
     * @return:  result
     * @author yuyd
     * @date:  
     */
    @RequestMapping(value = "/getPermitted",method = RequestMethod.POST)
    public Result getCurrentUserPermitted() {

        Subject currentUser = SecurityUtils.getSubject();
        // 拿到operator对象
        Operator operator = (Operator) currentUser.getPrincipal();
        //通过角色id获取权限信息
        String permissions = roleService.getJurisdiction4RoleId(operator.getOperatorRole());

        if (StringUtils.isBlank(permissions)){
            return  new Result(Constants.SYS_CODE.FAIL, Constants.SYS_CODE.FAIL);
        }
        return  new Result(Constants.SYS_CODE.SUCCESS, Constants.SYS_CODE.SUCCESS_MESSAGE,permissions.split(","));

    }

}
